
#include <util/common_macros.h>

#include "image.h"
/* ========================================================================== */
static boolean __bin_image_destroy(ImpObject * object) {
	ImpImage * Img;
	Img = IMP_IMAGE(object);

	if (Img->data) mem_free(Img->data);

	return TRUE;
}
static boolean __bin_image_copy(ImpObject * copy, ImpObject * object) {

	ImpImage * image = IMP_IMAGE(object);
	ImpImage * image_copy = IMP_IMAGE(copy);

	image_copy->height = image->height;
	image_copy->width = image->width;

	mem_copy(image->data, image_copy->data, image->npixels);

	return TRUE;
}
static void __image_class_init(ImpObjectClass * klass) {

	klass->object_attributes = NULL;
	klass->object_clone = NULL;
	klass->object_destroy = __bin_image_destroy;
	klass->object_copy = __bin_image_copy;

	//ImpArrayClass * array_klass;
	//array_klass = IMP_ARRAY_CLASS(klass);
	/* do nothing */
}
static void __image_init(ImpObject * object) {
	ImpImage * Img;
	Img = IMP_IMAGE(object);

	Img->data = NULL;

}
/* ========================================================================== */
ImpObjectClass * imp_image_get_class(void) {
	static ImpImageClass * klass = NULL;

	if (klass == NULL) {
		ImpObjectClassInfo info = {
			"ImpImage",
			sizeof (ImpImage),
			sizeof (ImpImageClass),
			(ImpObjectClassInitFunc) __image_class_init,
			(ImpObjectInitFunc) __image_init,
			(ImpArgSetFunc) NULL,
			(ImpArgGetFunc) NULL
		};

		ImpObjectClass * image_class = imp_object_class_new(IMP_OBJECT_TYPE, &info);
		klass = IMP_IMAGE_CLASS(image_class);
	}
	return IMP_OBJECT_CLASS(klass);
}
/* ========================================================================== */
boolean imp_image_set_data(ImpImage * Img, void * data, int height, int width, ImpImageType type) {

	Img->stride = imp_image_get_stride(width, type);
	Img->nchannels = Img->stride / width;
	Img->npixels = width * height;
	Img->nbytes = height * width * Img->nchannels; /* ====================================================================== */

	Img->data = data;

	Img->width = width;
	Img->height = height;
	Img->type = type;

	return TRUE;
}
boolean imp_image_constructor(ImpImage * Img, int width, int height, ImpImageType type) {

	_return_val_if_fail(width > 0 && height > 0, FALSE);

	Img->stride = imp_image_get_stride(width, type);
	Img->nchannels = Img->stride / width;
	Img->npixels = width * height;
	Img->nbytes = height * width * Img->nchannels;

	Img->data = mem_allocn(Img->nbytes, unsigned char);

	_return_val_if_fail(Img->data, FALSE);

	Img->width = width;
	Img->height = height;
	Img->type = type;
	
	return TRUE;
}
/* ========================================================================== */
ImpImage * imp_image_new(int width, int height, ImpImageType type) {
	ImpImage * Img;

	Img = IMP_IMAGE(imp_object_new(IMP_OBJECT_CLASS(imp_image_get_class())));

	if (imp_image_constructor(Img, width, height, type)) return Img;

	imp_object_delete(Img);
	return NULL;
}
